package com.huatek.authority.service;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.huatek.authority.entity.EfwDataRoleAuthority;
import com.huatek.authority.factory.DataAuthority;
import com.huatek.authority.factory.EntityFactory;
import com.huatek.authority.factory.FieldAuthority;
import com.huatek.base.service.BaseServiceImpl;
import com.huatek.base.tree.TreeEntity;

/****
 * 本类用于获取用户的数据权限.
 *
 * @author winner pan
 */
public class DataAuthorityServiceImpl extends BaseServiceImpl implements
		DataAuthorityService {


	/**
	 * 日志常量.
	 * **/
	private static final Logger LOGGER = Logger
			.getLogger(DataAuthorityServiceImpl.class);

	/***
	 * 获取用户的数据权限.
	 *
	 * @param userId
	 *            登录用户ID.
	 * @return Map<Class<? extends BaseEntity>,String> 类和对应的权限列表.
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Map<String,Map<String,FieldAuthority>>> getUserDataAuthority(final long userId) {
		return (Map<String, Map<String,Map<String,FieldAuthority>>>) hibernateTemplate
				.execute(new HibernateCallback() {
					public Object doInHibernate(final Session session)
							throws SQLException {
						// 获取数据权限列表
						List dataAuthoritylist = null;
						Query query = session
								.createQuery("select r from EfwUserDataAuthority t,EfwDataRoleAuthority r where r.efwDataRole.id=t.efwDataRole.id and t.fwAccount.id=?");
						query.setLong(0, userId);
						dataAuthoritylist = query.list();
						// 获取数据权限的ID列表
						Map<String, Map<String,Map<String,FieldAuthority>>> moduleMap = new HashMap<String, Map<String,Map<String,FieldAuthority>>>();
						for (int i = 0; i < dataAuthoritylist.size(); i++) {
							EfwDataRoleAuthority dataRoleAuthority = (EfwDataRoleAuthority) dataAuthoritylist
									.get(i);
							String menuIds = dataRoleAuthority.getEfwBusinessModule().getMenuIds();
							if(menuIds!=null){
								String[] menuIdArray = menuIds.split(",");
								for(int k=0;k<menuIdArray.length;k++){
									String menuId = menuIdArray[k];
									Map<String,Map<String,FieldAuthority>> entityAuthorityMap = null;
									if(moduleMap.get(menuId)==null){
										moduleMap.put(menuId, new HashMap<String, Map<String,FieldAuthority>>());
									}
									entityAuthorityMap = moduleMap.get(menuId);
									String entityName = dataRoleAuthority.getEfwSourceEntity().getEntityClass();
									StringBuffer fieldValues = new StringBuffer("'"+dataRoleAuthority.getFieldValue()+"'");
									String fieldName = dataRoleAuthority.getEfwSourceEntity().getEntityField();
									Map<String,FieldAuthority> fieldAuthorityMap = null;

									if(entityAuthorityMap.get(entityName)==null){
										entityAuthorityMap.put(entityName, new HashMap<String,FieldAuthority>());
									}
									fieldAuthorityMap = entityAuthorityMap.get(entityName);

									if(fieldAuthorityMap.containsKey(fieldName)){
										if(DataAuthority.isContains(fieldValues.toString(), fieldAuthorityMap.get(fieldName).getAuthorityDatas())){
											continue;
										}
										fieldValues.append(",").append(fieldAuthorityMap.get(fieldName).getAuthorityDatas());
									}else{
										FieldAuthority fieldAuthority = new FieldAuthority();
										fieldAuthority.setEntityName(entityName);
										fieldAuthority.setFieldName(fieldName);
										fieldAuthority.setExceptParam(dataRoleAuthority.getEfwSourceEntity().getExceptParam());
										fieldAuthorityMap.put(fieldName, fieldAuthority);
									}

									/*****
									 * 以下用于设置品类的小级别限制大级别的规则.
									 */
									if(TreeEntity.class.isAssignableFrom(EntityFactory.getAuthorityClass(entityName))&&fieldName.equals("style")){
										fieldValues = filterBigCategory(fieldValues);

									}
									//fieldAuthorityMap.put(fieldName, fieldValues.toString());
									fieldAuthorityMap.get(fieldName).setAuthorityDatas(fieldValues.toString());

								}

							}

						}

						//unlimitCustomer(moduleMap,session);
						return moduleMap;
					}
					/***
					 * 用于实现没有选择店铺的客户能够自动获取拥有所有店铺的权限.
					 * @param moduleMap 模块map
					 */
					/*private void unlimitCustomer(Map<String, Map<String,Map<String,FieldAuthority>>> authorityMap, final Session session){
						for(Map.Entry<String, Map<String,Map<String,FieldAuthority>>> moduleMap:authorityMap.entrySet()){
							for(Map.Entry<String,Map<String,FieldAuthority>> entityMap : moduleMap.getValue().entrySet()){
								if(entityMap.getKey().equals(DataAuthority.getShortName(CustomerShop.class.getName()))){
									Query query = session.createQuery("select distinct t.customerInfo from CustomerShop t where t.id in ("+entityMap.getValue().get("id").getAuthorityDatas()+")");
									List<CustomerInfo> customerInfoList = query.list();
									StringBuffer customerIds = new StringBuffer("");
									for(CustomerInfo customerInfo:customerInfoList){
										if(customerIds.length()==0){
											customerIds.append(customerInfo.getId());
										}else{
											customerIds.append(",").append(customerInfo.getId());
										}
									}
									entityMap.getValue().put("customerInfo", new FieldAuthority("id",customerIds.toString()));
								}
							}
						}
					}*/

					private StringBuffer filterBigCategory(
							StringBuffer fieldValues) {
						LinkedList<String> dataLink = new LinkedList();
						String[] fieldValueStr =  fieldValues.toString().replaceAll("'", "").split(",");
						for(int n=0; n<fieldValueStr.length; n++){
							boolean isAdd = false;
							for(int m=0;m<dataLink.size();m++){
								String linkStr = dataLink.get(m);
								if(linkStr.length()>fieldValueStr[n].length()&&linkStr.startsWith(fieldValueStr[n])){
									isAdd = true;
									break;
								}else if(linkStr.length()<fieldValueStr[n].length()&&fieldValueStr[n].startsWith(linkStr)){
									dataLink.remove(m);
									dataLink.add(fieldValueStr[n]);
									isAdd = true;
									break;
								}
							}
							if(!isAdd){
								dataLink.add(fieldValueStr[n]);
							}
						}
						for(int z=0;z<dataLink.size();z++){
							if(z==0){
								fieldValues = new StringBuffer("'"+dataLink.get(0)+"'");
							}else{
								fieldValues.append(",").append("'"+dataLink.get(z)+"'");
							}

						}
						return fieldValues;
					}
				});

	}

}
